package com.ng.service.impl;

import com.ng.common.constant.MessageConstant;
import com.ng.common.constant.PasswordConstant;
import com.ng.common.constant.StatusConstant;
import com.ng.common.context.BaseContext;
import com.ng.common.exception.BaseException;
import com.ng.common.result.PageResult;
import com.ng.common.utils.VOUtils;
import com.ng.mapper.UserMapper;
import com.ng.model.dto.UserDTO;
import com.ng.model.dto.UserLoginDTO;
import com.ng.model.dto.UserPageDTO;
import com.ng.model.po.User;
import com.ng.service.UserService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 用户接口 ServiceImpl
 *
 * @author Ng
 * @date 2024/03/07
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public User login(UserLoginDTO userLoginDTO) {

        String userName = userLoginDTO.getUserName();
        String passWord = userLoginDTO.getPassWord();

        User user = userMapper.login(userName);

        // 处理各种异常情况（用户名不存在、密码不对、账号被锁定）
        // 1. 账号是否存在
        if (user == null) {
            throw new BaseException(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        // 对前端传过来的密码进行 md5 加密
        // passWord = DigestUtils.md5DigestAsHex(passWord.getBytes(StandardCharsets.UTF_8));
        // 2. 密码是否错误
        if (!passWord.equals(user.getPassWord())) {
            throw new BaseException(MessageConstant.PASSWORD_ERROR);
        }
        // 3. 账号是否锁定
        if (Objects.equals(user.getStatus(), StatusConstant.DISABLE)) {
            throw new BaseException(MessageConstant.ACCOUNT_LOCKED);
        }

        return user;
    }

    @Override
    public void save(UserDTO userDTO) {

        User user = new User();
        // BeanUtils.copyProperties(userDTO, user);  // 性能及响应链问题-少用

        user.setUserName(userDTO.getUserName());
        // 设置密码，默认密码设置‘123456‘
        // user.setPassWord(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes(StandardCharsets.UTF_8)));
        user.setPassWord(PasswordConstant.DEFAULT_PASSWORD);
        user.setName(userDTO.getName());
        user.setPhone(userDTO.getPhone());
        user.setSex(userDTO.getSex());

        // 设置账号状态 0：启用，1：禁用
        user.setStatus(StatusConstant.ENABLE);
        user.setCreateBy(BaseContext.getCurrentId().toString());
        user.setChangeBy(BaseContext.getCurrentId().toString());

        userMapper.insert(user);
    }

    @Override
    public void delete(Long userId) {

        userMapper.deleteById(userId);
    }

    @Override
    public void update(UserDTO userDTO) {

        User user = new User();
        user.setUserId(userDTO.getUserId());
        user.setUserName(userDTO.getUserName());
        user.setName(userDTO.getName());
        user.setPhone(userDTO.getPhone());
        user.setSex(userDTO.getSex());

        userMapper.update(user);
    }

    @Override
    public void auth(Short status, Long userId) {

        User user = User.builder()
                .userId(userId)
                .status(status)
                .build();
        userMapper.update(user);
    }

    @Override
    public User getById(Long userId) {

        User user = userMapper.getById(userId);

        // 敏感信息置 *
        user.setPassWord("******");
        user.setPhone(VOUtils.hidePhone(user.getPhone()));
        return user;
    }

    @Override
    public PageResult pageQuery(UserPageDTO userPageDTO) {

        int dtoPage = userPageDTO.getPage();
        int dtoPageSize = userPageDTO.getPageSize();

        // 通过 MyBatis 插件 PageHelpr 进行分页查询
        PageHelper.startPage(userPageDTO.getPage(), userPageDTO.getPageSize());

        Page<User> page = userMapper.pageQuery(userPageDTO);

        long total = page.getTotal();
        List<User> userList = page.getResult();

        // 敏感信息置 *
        for (User user : userList) {
            user.setPassWord("******");
            user.setPhone(VOUtils.hidePhone(user.getPhone()));
        }

        return new PageResult(total, userList);
    }

    @Override
    public Integer countByUserId(Map map) {
        return userMapper.countByUserId(map);
    }
}
